
/*
 *
 * Copyright (c) 2006 P.J.Leonard
 * 
 * http://www.frinika.com
 * 
 * This file is part of Frinika.
 * 
 * Frinika is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * Frinika is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with Frinika; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package sane;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import uk.ac.bath.domains.IP.IPView;
import uk.ac.bath.util.MyRandom;

/**
 *
 * @author pjl
 */
class ProgressViewer {

    CartPole cp;
    IPView view;
    Network net;
    static final float one_degree = 0.0174532f;	/* 2pi/360 */

    static final float six_degrees = 0.1047192f;
    static final float twelve_degrees = 0.2094384f;
    static final float fifty_degrees = 0.87266f;
    private boolean manual = false;

    ProgressViewer() {
        cp = new CartPole(0, 0, 0, 0);
        view = new IPView(null);  // TODO

        view.setModel(cp);
        int delay = 50;
        Timer timer = new Timer(delay, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                tick();
                view.repaint();
            }
        });

        timer.setRepeats(true);
        timer.start();

    }

    void setManual(boolean selected) {
        manual = selected;
    }

    void tick() {
        int y;

        if (net == null) {
            return;
        }

        net.setIn(0, cp.x);
        net.setIn(1, cp.x_dot);
        net.setIn(2, cp.theta);
        net.setIn(3, cp.theta_dot);
        net.setIn(4, 0.5f);
        net.tick();   /*-- activate the network based on the input --*/

        /*-- decide which way to push via which output unit is greater --*/

        y=0;
        
        if (manual && !view.isHumanActive()) {
            y = 0;
        } else if (view.isHumanActive()) {

            if (view.getFx() > 0) {
                y = 1;
            } else if (view.getFx() < 0) {
                y = -1;
            }

        } else {
            if (net.out(0) > net.out(1)) {
                y = -1;
            } else {
                y = 1;
            }
        }

        /*--- Apply action to the simulated cart-pole ---*/
        //        System.out.println(y+ " | " + cp );

        cp.tick(y);

    /*--- Check for failure.  If so, return steps ---*/
//        if (cp.x < -2.4 || cp.x > 2.4 || cp.theta < -twelve_degrees ||
//                cp.theta > twelve_degrees) {
//            reset();
//        }

    }

    void reset() {
        float x = (float) (0.5 * (MyRandom.nextInt(4800) / 1000.0 - 2.4));
        float x_dot = (float) (0.5 * (MyRandom.nextInt(2000) / 1000.0 - 1.0));
        float theta = (float) (0.5 * (MyRandom.nextInt(400) / 1000.0 - .2));
        float theta_dot = (float) (0.5 * (MyRandom.nextInt(3000) / 1000.0 - 1.5));
        cp.reset(x, x_dot, theta, theta_dot);
    }

    void setNet(Network net) {
        this.net = net;
    }

    public static void main(String args[]) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        Context c = new Context();

        ProgressViewer view = new ProgressViewer();

        Population pop = new Population(c, view);

        Network net = pop.createRandomNet();
        view.setNet(net);

        frame.setSize(400, 400);
        frame.setContentPane(view.view);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
